#ifndef __BMI088_H_
#define __BMI088_H_

#include "main.h"
#include "gpio.h"
#include <stdbool.h>
#include <stdint.h>
#include "bmi088reg.h"
#include "stm32f4xx_hal.h"


#define BMI088_SPI hspi1


#pragma once

// 枚举保存类型值
typedef enum bmi088_error_e
{
    NO_ERROR = 0,
    ACC_CHIP_ID_ERR = 0x01,
    ACC_DATA_ERR = 0x02,
    GYRO_CHIP_ID_ERR = 0x04,
    GYRO_DATA_ERR = 0x08,
} __packed bmi088_error_e;

/*imu 配置结构体*/
typedef struct
{
    uint8_t reserved : 1;   // 保留位
    uint8_t acc_bwp : 3;    /*加速度过采样率 有以下选择参数 其详细定义在 bmi088reg.h 文件中
                                  ACC_CONF_RESERVED
                                  ACC_CONF_BWP_OSR4
                                  ACC_CONF_BWP_OSR2
                                  ACC_CONF_BWP_NORM */
    uint8_t acc_odr : 4;    /*加速度采集频率 bwp 和 odr 组合决定了输出数据速率 你可以选择以下几种值：
                                  ACC_CONF_ODR_12_5_Hz
                                  ACC_CONF_ODR_25_Hz
                                  ACC_CONF_ODR_50_Hz
                                  ACC_CONF_ODR_100_Hz
                                  ACC_CONF_ODR_200_Hz
                                  ACC_CONF_ODR_400_Hz
                                  ACC_CONF_ODR_800_Hz
                                  ACC_CONF_ODR_1600_Hz */
    uint8_t acc_range : 2;  /*加速度量程
                                  ACC_RANGE_3G 0x00
                                  ACC_RANGE_6G 0x01
                                  ACC_RANGE_12G 0x02
                                  ACC_RANGE_24G 0x03
                                 */
    uint8_t gyro_range;     /* 陀螺仪量程
                                     GYRO_RANGE_2000_DEG_S
                                     GYRO_RANGE_1000_DEG_S
                                     GYRO_RANGE_500_DEG_S
                                     GYRO_RANGE_250_DEG_S
                                     GYRO_RANGE_125_DEG_S*/
    uint8_t gyro_bandwidth; /* 陀螺仪滤波器带宽 0x00 ～ 0x07 ，每个输出速率对应一个输出滤波带宽
                                 GYRO_ODR_2000Hz_BANDWIDTH_532Hz
                                 GYRO_ODR_2000Hz_BANDWIDTH_230Hz
                                 GYRO_ODR_1000Hz_BANDWIDTH_116Hz
                                 GYRO_ODR_400Hz_BANDWIDTH_47Hz
                                 GYRO_ODR_200Hz_BANDWIDTH_23Hz
                                 GYRO_ODR_100Hz_BANDWIDTH_12Hz
                                 GYRO_ODR_200Hz_BANDWIDTH_64Hz
                                 GYRO_ODR_100Hz_BANDWIDTH_32Hz*/

} __packed bmi088_config_struct_t;

/*acc fifo 配置结构体 包含中断以及fifo等高级功能的设置参数*/
typedef struct
{
    uint8_t fifo_downs;   // fifo 低速率输出参数 一般为0 目的是更改输出频率 out_freq = odr/(2^downs)
    uint16_t fifo_wtm;    // fifi水位线 一个13bit数据
    uint8_t fifo_mode;    // fifo配置 0 流模式 | 1 fifo模式
    uint8_t fifo_accen;   // 使能acc_fifo功能  0 关闭 | 1 开启
    uint8_t fifo_int1_en; // int1使能
    uint8_t fifo_int2_en; // int2使能

    uint8_t int1_out; // 使能输出引脚中断
    uint8_t int1_od;  // 引脚设置:推挽0/开漏1
    uint8_t int1_lvl; // 中断级别:低0/高1
    uint8_t int1_in;  // 使能输入引脚中断

    uint8_t int2_out; // 使能输入引脚中断
    uint8_t int2_od;  // 使能输出引脚中断
    uint8_t int2_lvl; // 引脚设置:推挽0/开漏1
    uint8_t int2_in;  // 中断级别:低0/高1

    uint8_t int2_drdy; // 数据准备好 映射到 中断2
    uint8_t int2_fwm;  // FIFO水位标记 映射到 中断2
    uint8_t int2_fful; // FIFO溢出 映射到 中断2
    uint8_t int1_drdy; // 数据准备好 映射到 中断1
    uint8_t int1_fwm;  // FIFO水位标记 映射到 中断1中断
    uint8_t int1_full; // FIFO溢出 映射到 中断1

} __packed bmi088_acc_fifo_config_struct_t;

/* gyro fifo 配置结构体 包含中断以及fifo等高级功能的设置参数*/
typedef struct
{

} __packed bmi088_gyro_fifo_config_struct_t;

// 加速度原始数据
typedef struct acc_raw_data_t
{
    float x;
    float y;
    float z;
} __packed acc_raw_data_t;

// 陀螺仪原始数据
typedef struct gyro_raw_data_t
{
    float roll;
    float pitch;
    float yaw;
} __packed gyro_raw_data_t;

// 加速度寄存器数据
typedef struct acc_data_t
{
    acc_raw_data_t acc_raw_data;
    float sensor_diff_time; // 时间差
    float sensor_time;// 时间戳
    float temperature;
    bool enable_self_test;
} __packed acc_data_t;

// 陀螺仪寄存器数据
typedef struct gyro_data_t
{
    gyro_raw_data_t gyro_raw_data;
    bool enable_self_test;
} __packed gyro_data_t;

// bmi数据总结构体
typedef struct bmi088_data_t
{
    acc_data_t acc_data;
    gyro_data_t gyro_data;
    bmi088_error_e bmi088_error;
} __packed bmi088_data_t;

/**************基础函数*************/

void WriteDataToAcc(uint8_t addr, uint8_t data);
void WriteDataToGyro(uint8_t addr, uint8_t data);
void ReadSingleDataFromAcc(uint8_t addr, uint8_t *data);
void ReadSingleDataFromGyro(uint8_t addr, uint8_t *data);
void ReadMultiDataFromAcc(uint8_t addr, uint8_t len, uint8_t *data);
void ReadMultiDataFromGyro(uint8_t addr, uint8_t len, uint8_t *data);

/**************校验函数**************/
/***********************************/

bmi088_error_e VerifyAccChipID(void);
bmi088_error_e VerifyGyroChipID(void);
bmi088_error_e VerifyAccSelfTest(void);
bmi088_error_e VerifyGyroSelfTest(void);

/**************初始化函数**************/
/************************************/

bmi088_error_e BMI088_INIT(void);
void BMI088_CONF_INIT(bmi088_config_struct_t *arg);
void BMI088_ACC_FIFO_INT(bmi088_acc_fifo_config_struct_t *arg);
/***************功能函数**************/
/************************************/

void ReadAccData(acc_raw_data_t *data);
void ReadGyroData(gyro_raw_data_t *data);
void ReadAccSensorTime(float *time);
void ReadAccDataAndTime(acc_data_t *arg);
void ReadAccTemperature(float *temp);
void ReadACC_FIFO_Data(acc_data_t *arg);
extern bmi088_data_t BMI088_Struct;
#endif